package com.vpen.picupload.aspect;

import com.vpen.picupload.annotation.ColorAnnotation;
import com.vpen.picupload.enums.Color;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @version 1.0
 * @author: Vpen
 * @date: 2021/8/5 23:47
 * @content:
 */
@Component
@Aspect
@Slf4j
public class ColorAspect {
    /**
     * @author:韦鹏
     * @desc: 定义切入点
     */
    @Pointcut("@annotation(com.vpen.picupload.annotation.ColorAnnotation)")
    public void pc() {
        // Pointcut methods should have empty body
    }

    @Around(value = "pc()&&@annotation(color)")
    public Object around(ProceedingJoinPoint point, ColorAnnotation color) throws Throwable {
        log.info(color.name());
        log.info("{}",color.type());

        point.proceed();
        Method method = ((MethodSignature) point.getSignature()).getMethod();
        Object[] args = point.getArgs();

        String name = parseExpression(color.name(), method, args);
        String id = parseExpression(color.id(), method, args);

        log.info("{}",name);
        log.info("{}",name.getClass());

        log.info("{}",id);

        return null;
    }



    /**
     * 解析
     * @param: expressionString
     * @param: method
     * @param: args
     * @return:
     */
    private String parseExpression(String expressionString, Method method, Object[] args) {
        //获取被拦截方法参数名列表
        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNameArr = discoverer.getParameterNames(method);
        //SPEL解析
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();
        for (int i = 0; i < paramNameArr.length; i++) {
            context.setVariable(paramNameArr[i], args[i]);
        }
        String result = parser.parseExpression(expressionString).getValue(context, String.class);
        return result;
    }
}
